from waflib.Configure import ConfigurationContext, conf
from platform_capabilities import get_capability_dict

@conf
def get_board(ctx):
    if isinstance(ctx, ConfigurationContext):
        return ctx.options.board
    else:
        return ctx.env.BOARD

@conf
def is_bigboard(ctx):
    return '_bb' in ctx.get_board()


# Platform specific predicates

@conf
def is_tintin(ctx):
    return ctx.get_board() in ('bigboard', 'bb2', 'ev2_4', 'v1_5', 'v2_0')

@conf
def is_snowy(ctx):
    return ctx.get_board().startswith('snowy')

@conf
def is_spalding(ctx):
    return ctx.get_board().startswith('spalding')

@conf
def is_silk(ctx):
    return ctx.get_board().startswith('silk')

@conf
def is_cutts(ctx):
    return ctx.get_board().startswith('cutts')

@conf
def is_robert(ctx):
    return ctx.get_board().startswith('robert')

@conf
def is_asterix(ctx):
    return ctx.get_board().startswith('asterix')

@conf
def is_obelix(ctx):
    return ctx.get_board().startswith('obelix')

@conf
def is_obelix_evt(ctx):
    return ctx.get_board() == 'obelix_evt'

@conf
def is_obelix_bb(ctx):
    return ctx.get_board() == 'obelix_bb'

@conf
def is_obelix_dvt(ctx):
    return ctx.get_board() == 'obelix_dvt'

@conf
def is_obelix_pvt(ctx):
    return ctx.get_board() == 'obelix_pvt'

@conf
def is_obelix_bb2(ctx):
    return ctx.get_board() == 'obelix_bb2'

@conf
def get_platform_name(ctx):
    if is_tintin(ctx):
        return "tintin"
    elif ctx.get_board() == 'snowy_emery':
        return "snowy_emery"
    elif is_snowy(ctx):
        return "snowy"
    elif is_spalding(ctx):
        return "spalding"
    elif is_silk(ctx):
        return "silk"
    elif is_cutts(ctx):
        return "calculus"
    elif is_robert(ctx):
        return "robert"
    elif is_asterix(ctx):
        return "asterix"
    elif is_obelix(ctx):
        return "obelix"
    else:
        return "unknown"

# Composite platform predicates

@conf
def is_snowy_compatible(ctx):
    return (ctx.is_snowy() or ctx.is_spalding())


# Platform features

@conf
def get_qemu_machine(ctx):
    if is_tintin(ctx):
        return 'pebble-bb2'
    elif ctx.get_board() == 'snowy_emery':
        return 'pebble-snowy-emery-bb'
    elif is_snowy(ctx):
        return 'pebble-snowy-bb'
    elif is_spalding(ctx):
        return 'pebble-s4-bb'
    elif is_silk(ctx):
        return 'pebble-silk-bb'
    elif is_cutts(ctx):
        return 'pebble-cutts-bb'
    elif is_robert(ctx):
        return 'pebble-robert-bb'
    else:
        return 'unknown'


@conf
def get_qemu_cpu(ctx):
    if is_tintin(ctx):
        return 'cortex-m3'
    elif is_snowy(ctx):
        return 'cortex-m4'
    elif is_spalding(ctx):
        return 'cortex-m4'
    elif is_silk(ctx):
        return 'cortex-m4'
    elif is_cutts(ctx):
        return 'cortex-m4'
    elif is_robert(ctx):
        return 'cortex-m4'
    elif is_asterix(ctx):
        return 'cortex-m4'
    elif is_obelix(ctx):
        return 'cortex-star-mc1'
    else:
        return 'unknown'


@conf
def get_qemu_extflash_device_type(ctx):
    if is_tintin(ctx):
        return '-mtdblock'
    elif is_snowy(ctx):
        return '-pflash'
    elif is_spalding(ctx):
        return '-pflash'
    elif is_silk(ctx):
        return '-mtdblock'
    elif is_cutts(ctx):
        return '-pflash'
    elif is_robert(ctx):
        return '-pflash'
    else:
        return None


@conf
def has_touch(ctx):
    if is_tintin(ctx):
        return False
    elif is_snowy(ctx):
        return False
    elif is_spalding(ctx):
        return False
    elif is_silk(ctx):
        return False
    elif is_cutts(ctx):
        return True
    elif is_robert(ctx):
        return False
    elif is_asterix(ctx):
        return False
    elif is_obelix(ctx):
        return True
    else:
        return None


@conf
def get_hrm(ctx):
    if is_robert(ctx):
        return "AS7000"
    elif is_silk(ctx):
        return "AS7000"
    elif is_obelix(ctx):
        return "GH3X2X"
    else:
        return None


@conf
def capabilities_dict(ctx):
    board = ctx.get_board()
    # capabilities will never be None. An exception is raised if it fails.
    capabilities = get_capability_dict(ctx, board)
    return capabilities


@conf
def capability(ctx, capability_str):
    capabilities = ctx.capabilities_dict()
    return capabilities[capability_str]


@conf
def add_platform_defines(ctx, env):
    if ctx.is_tintin():
        bit_depth = 1
        platform = 'TINTIN'
    elif ctx.is_snowy():
        bit_depth = 8
        platform = 'SNOWY'
    elif ctx.is_spalding():
        bit_depth = 8
        platform = 'SPALDING'
    elif ctx.is_silk():
        bit_depth = 1
        platform = 'SILK'
    elif ctx.is_cutts():
        bit_depth = 8
        platform = 'CALCULUS'
    elif ctx.is_robert():
        bit_depth = 8
        platform = 'ROBERT'
    elif ctx.is_asterix():
        bit_depth = 1
        platform = 'ASTERIX'
    elif ctx.is_obelix():
        bit_depth = 8
        platform = 'OBELIX'
    else:
        ctx.fatal('No platform specified for {}!'.format(ctx.options.board))

    env.append_value(
        'DEFINES', ['USE_STDPERIPH_DRIVER=1',
                    'BOARD_{}=1'.format(ctx.options.board.upper()),
                    'PLATFORM_{}=1'.format(platform),
                    'MICRO_FAMILY_{}=1'.format(env.MICRO_FAMILY),
                    'SCREEN_COLOR_DEPTH_BITS={}'.format(bit_depth),
                    'MIN_SDK_VERSION={}'.format(env.MIN_SDK_VERSION)])
    if 'NRF5' in env.MICRO_FAMILY:
        env.append_value('DEFINES', 'MICRO_FAMILY_NRF5=1')

    for cap, val in ctx.capabilities_dict().items():
        env.append_value('DEFINES', "CAPABILITY_%s=%s" % (cap, int(val)))

# Build

def configure(ctx):
    pass


def build(ctx):
    pass


# vim:filetype=python
